package com.lefevre.cms.web.action.theme;

import com.fasterxml.jackson.core.type.TypeReference;
import com.lefevre.cms.bean.RequestResult;
import com.lefevre.cms.bean.ResultCode;
import com.lefevre.cms.bean.theme.*;
import com.lefevre.cms.service.theme.ThemeService;
import com.lefevre.cms.utils.*;
import com.lefevre.cms.web.action.SystemException;
import com.lefevre.cms.web.action.TextFilterManage;
import com.lefevre.cms.web.action.fileSystem.localImpl.LocalFileManage;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOCase;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.apache.commons.io.filefilter.SuffixFileFilter;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.MessageSource;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.Validator;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 模板目录管理
 */
@Controller
@RequestMapping("/control/template/manage")
public class TemplateManageAction {
    private static final Logger logger = LoggerFactory.getLogger(TemplateManageAction.class);
    @Resource
    TemplateManage templateManage;
    @Resource
    LocalFileManage localFileManage;
    @Resource
    TextFilterManage textFilterManage;
    @Resource
    MessageSource messageSource;
    @Resource(name = "themeServiceImpl")
    private ThemeService themeService;
    @Resource(name = "templateValidator")
    private Validator validator;

    /**
     * 模板管理 添加模板显示
     */
    @ResponseBody
    @RequestMapping(params = "method=add", method = RequestMethod.GET)
    public String addUI() throws Exception {
        return JsonUtils.toJSONString(new RequestResult(ResultCode.SUCCESS, null));
    }

    /**
     * 模板管理 添加
     */
    @ResponseBody
    @RequestMapping(params = "method=add", method = RequestMethod.POST)
    public String add(Themes formbean, BindingResult result, MultipartHttpServletRequest request) throws Exception {
        Map<String, Object> error = new HashMap<>();

        //数据校验
        this.validator.validate(formbean, result);
        if (result.hasErrors()) {
            List<FieldError> fieldErrorList = result.getFieldErrors();
            if (fieldErrorList.size() > 0) {
                for (FieldError fieldError : fieldErrorList) {
                    error.put(fieldError.getField(), messageSource.getMessage(fieldError, null));
                }
            }
        }
        if (error.size() == 0) {
            Themes themes = new Themes();
            themes.setName(formbean.getName().trim());
            themes.setDirName(formbean.getDirName().trim());
            themes.setIntroduction(formbean.getIntroduction());

            //图片上传
            List<MultipartFile> files = request.getFiles("uploadImage");
            for (MultipartFile file : files) {
                if (!file.isEmpty()) {
                    //验证文件类型
                    List<String> formatList = new ArrayList<>();
                    formatList.add("gif");
                    formatList.add("jpg");
                    formatList.add("jpeg");
                    formatList.add("bmp");
                    formatList.add("png");
                    boolean authentication = FileUtil.validateFileSuffix(file.getOriginalFilename(), formatList);
                    if (authentication) {
                        //取得文件后缀		
                        String ext = FileUtil.getExtension(file.getOriginalFilename());
                        //文件保存目录
                        String pathDir = "";

                        if (PathUtil.isStartupFromJar()) {//jar启动
                            pathDir = "common" + File.separator + formbean.getDirName() + File.separator;
                        } else {//IDE启动
                            pathDir = "static" + File.separator + "common" + File.separator + formbean.getDirName() + File.separator;
                        }

                        //构建文件名称
                        String fileName = "thumbnail." + ext;
                        themes.setThumbnailSuffix(ext);

                        //生成文件保存目录
                        FileUtil.autoCreateFolder(pathDir);
                        //保存文件

                        try (FileOutputStream fileoutstream = new FileOutputStream(new File(PathUtil.autoRootPath() + File.separator + pathDir, fileName));) {
                            //文件输出流

                            //写入硬盘
                            fileoutstream.write(file.getBytes());
                        } catch (Exception e) {
                            logger.error("写文件", e);
                        }
                    } else {
                        result.rejectValue("thumbnailSuffix", "errors.required", new String[]{"图片格式错误"}, "");
                    }
                }
                break;//只有一个文件上传框
            }
            List<Layout> layoutList = templateManage.newTemplate(themes.getDirName());
            themeService.saveTemplate(themes, layoutList);
        }
        if (error.size() > 0) {
            return JsonUtils.toJSONString(new RequestResult(ResultCode.FAILURE, error));
        } else {
            return JsonUtils.toJSONString(new RequestResult(ResultCode.SUCCESS, null));
        }
    }

    /**
     * 模板管理 修改模板显示
     */
    @ResponseBody
    @RequestMapping(params = "method=edit", method = RequestMethod.GET)
    public String editUI(String dirName) throws Exception {
        Map<String, String> error = new HashMap<>();
        if (dirName != null && !"".equals(dirName.trim())) {
            Themes themes = themeService.findTemplateByDirName(dirName);
            if (themes != null) {
                return JsonUtils.toJSONString(new RequestResult(ResultCode.SUCCESS, themes));
            } else {
                error.put("templates", "模板不存在");
            }
        } else {
            error.put("dirName", "目录名称不能为空");
        }
        return JsonUtils.toJSONString(new RequestResult(ResultCode.FAILURE, error));
    }

    /**
     * 模板管理 修改
     *
     * @param imagePath 图片路径
     */
    @ResponseBody
    @RequestMapping(params = "method=edit", method = RequestMethod.POST)
    public String edit(Themes formbean, String imagePath, MultipartHttpServletRequest request) throws Exception {
        Map<String, String> error = new HashMap<>();

        Themes old_themes = themeService.findTemplateByDirName(formbean.getDirName().trim());
        if (formbean.getDirName() == null || "".equals(formbean.getDirName().trim())) {
            error.put("dirName", "目录名称不能为空");
        } else {
            old_themes = themeService.findTemplateByDirName(formbean.getDirName().trim());
            if (old_themes == null) {
                error.put("templates", "模板不存在");
            }
        }
        if (formbean.getName() == null || "".equals(formbean.getName().trim())) {
            error.put("name", "模板名称不能为空");
        }

        Themes themes = new Themes();
        //标记是否删除旧图片文件
        boolean flag = false;
        if (error.size() == 0) {

            themes.setName(formbean.getName().trim());
            themes.setDirName(formbean.getDirName().trim());
            themes.setIntroduction(formbean.getIntroduction());

            if (imagePath != null && !"".equals(imagePath.trim())) {
                themes.setThumbnailSuffix(old_themes.getThumbnailSuffix());
            } else {
                themes.setThumbnailSuffix(null);
            }

            //验证文件类型
            List<String> formatList = new ArrayList<>();
            formatList.add("gif");
            formatList.add("jpg");
            formatList.add("jpeg");
            formatList.add("bmp");
            formatList.add("png");

            //图片上传
            List<MultipartFile> files = request.getFiles("uploadImage");
            if (files.size() == 0) {
                flag = true;
            }

            for (MultipartFile file : files) {
                if (file.isEmpty()) {//如果图片已上传

                    if (imagePath != null && !"".equals(imagePath.trim())) {
                        boolean authentication = FileUtil.validateFileSuffix(imagePath.trim(), formatList);
                        if (authentication) {
                            //取得文件后缀
                            String ext = FileUtil.getExtension(imagePath.trim());
                            themes.setThumbnailSuffix(ext);
                        } else {
                            error.put("thumbnailSuffix", "图片格式错误");
                        }
                    } else {
                        flag = true;
                        themes.setThumbnailSuffix(null);
                    }
                }
                if (!file.isEmpty()) {
                    boolean authentication = FileUtil.validateFileSuffix(file.getOriginalFilename(), formatList);
                    if (authentication) {
                        //取得文件后缀		
                        String ext = FileUtil.getExtension(file.getOriginalFilename());
                        //文件保存目录
                        String pathDir = "";
                        if (PathUtil.isStartupFromJar()) {//jar启动
                            pathDir = "common" + File.separator + formbean.getDirName() + File.separator;
                        } else {//IDE启动
                            pathDir = "static" + File.separator + "common" + File.separator + formbean.getDirName() + File.separator;
                        }
                        //构建文件名称
                        String fileName = "thumbnail." + ext;
                        if (old_themes.getThumbnailSuffix() != null && !old_themes.getThumbnailSuffix().equalsIgnoreCase(ext)) {
                            flag = true;
                        }
                        themes.setThumbnailSuffix(ext);
                        //生成文件保存目录
                        FileUtil.createFolder(pathDir);
                        //保存文件
                        try (FileOutputStream fileoutstream = new FileOutputStream(new File(PathUtil.autoRootPath() + File.separator + pathDir, fileName));) {
                            //文件输出流
                            //写入硬盘
                            fileoutstream.write(file.getBytes());
                        } catch (Exception e) {
                            logger.error("写文件", e);
                        }
                    } else {
                        error.put("thumbnailSuffix", "图片格式错误");
                    }
                }
                break;//只有一个文件上传框
            }
        }
        if (error.size() == 0) {
            themeService.updateTemplate(themes);
            if (flag) {//删除旧文件
                String pathDir = "";
                if (PathUtil.isStartupFromJar()) {//jar启动
                    pathDir = "common" + File.separator + old_themes.getDirName() + File.separator + "thumbnail." + old_themes.getThumbnailSuffix();
                } else {//IDE启动
                    pathDir = "static" + File.separator + "common" + File.separator + old_themes.getDirName() + File.separator + "thumbnail." + old_themes.getThumbnailSuffix();
                }
                //删除旧路径文件
                FileUtil.autoDeleteFile(pathDir);
            }
        }

        if (error.size() > 0) {
            return JsonUtils.toJSONString(new RequestResult(ResultCode.FAILURE, error));
        } else {
            return JsonUtils.toJSONString(new RequestResult(ResultCode.SUCCESS, null));
        }
    }

    /**
     * 模板管理 删除模板
     */
    @ResponseBody
    @RequestMapping(params = "method=delete", method = RequestMethod.POST)
    public String delete(String dirName) throws Exception {
        Map<String, String> error = new HashMap<>();

        if (dirName != null && !"".equals(dirName.trim())) {
            Themes themes = themeService.findTemplateByDirName(dirName.trim());
            if (themes != null) {
                //替换路径中的..号
                dirName = FileUtil.toRelativePath(dirName);
                themeService.deleteTemplate(dirName.trim());

                if (PathUtil.isStartupFromJar()) {//jar启动
                    //删除资源文件
                    this.removeDirectory("common" + File.separator + dirName.trim() + File.separator);
                } else {//IDE启动
                    //删除资源文件
                    this.removeDirectory("static" + File.separator + "common" + File.separator + dirName.trim() + File.separator);
                }
                //删除模板文件
                this.removeDirectory("WEB-INF" + File.separator + "front" + File.separator + "templates" + File.separator + dirName.trim() + File.separator);

                //删除模板图片文件
                localFileManage.removeDirectory("file" + File.separator + "template" + File.separator + dirName.trim() + File.separator);
                return JsonUtils.toJSONString(new RequestResult(ResultCode.SUCCESS, null));
            } else {
                error.put("templates", "模板不存在");
            }
        } else {
            error.put("dirName", "目录名称不能为空");
        }
        return JsonUtils.toJSONString(new RequestResult(ResultCode.FAILURE, error));
    }

    /**
     * 模板管理 导出模板
     *
     * @param dirName 模板目录名称
     */
    @ResponseBody
    @RequestMapping(params = "method=export", method = RequestMethod.POST)
    public String export(String dirName) throws Exception {
        Map<String, String> error = new HashMap<>();
        if (dirName != null && !"".equals(dirName.trim())) {
            //替换路径中的..号
            dirName = FileUtil.toRelativePath(dirName);

            //构建文件名称
            String tempDirName = UUIDUtil.getUUID32();

            //创建临时目录
            String pathDir = "WEB-INF" + File.separator + "data" + File.separator + "temp" + File.separator + tempDirName + File.separator + dirName + File.separator;

            //取得文件保存目录的真实路径
            String realpathDir = PathUtil.defaultExternalDirectory() + File.separator + pathDir;
            File saveDir = new File(realpathDir);//生成目录
            if (!saveDir.exists()) {//如果目录不存在
                saveDir.mkdirs();//生成目录
            }

            ThemeData themeData = new ThemeData();
            //读取模板数据
            Themes themes = themeService.findTemplateByDirName(dirName);
            //读取布局数据
            List<Layout> layoutList = themeService.findLayout(dirName);
            //读取版块数据
            List<Forum> forumList = themeService.findForumByDirName(dirName);
            themeData.setThemes(themes);
            themeData.setLayoutList(layoutList);
            themeData.setForumList(forumList);
            //备份到临时目录
            FileUtil.writeStringToFile(pathDir + "templateData.data", JsonUtils.toJSONString(themeData), "UTF-8", false);

            //创建模板目录
            String template_dir_path = realpathDir + "templates" + File.separator;
            File template_dir = new File(template_dir_path);//生成目录
            if (!template_dir.exists()) {//如果目录不存在
                template_dir.mkdirs();//生成目录
            }
            //创建资源文件目录
            String file_dir_path = realpathDir + "common" + File.separator;
            File file_dir = new File(file_dir_path);//生成目录
            if (!file_dir.exists()) {//如果目录不存在
                file_dir.mkdirs();//生成目录
            }
            //创建模板上传文件目录
            String upload_dir_path = realpathDir + "uploadFile" + File.separator;
            File upload_dir = new File(upload_dir_path);//生成目录
            if (!upload_dir.exists()) {//如果目录不存在
                upload_dir.mkdirs();//生成目录
            }
            if (PathUtil.isStartupFromJar()) {//jar启动
                //模板源目录
                String template_source = "WEB-INF" + File.separator + "front" + File.separator + "templates" + File.separator + dirName + File.separator;
                //复制模板文件到临时目录
                FileUtil.copyDirectory(template_source, pathDir + "templates" + File.separator);

                //资源文件源目录
                String file_source = "common" + File.separator + dirName + File.separator;
                //复制模板文件到临时目录
                FileUtil.copyDirectory(file_source, pathDir + "common" + File.separator);
            } else {//IDE启动

                //模板源目录
                String template_source = "WEB-INF" + File.separator + "front" + File.separator + "templates" + File.separator + dirName + File.separator;
                //复制模板文件到临时目录
                this.copyToExternalDirectory(template_source, pathDir + "templates" + File.separator);

                //资源文件源目录
                String file_source = "static" + File.separator + "common" + File.separator + dirName + File.separator;
                //复制模板文件到临时目录
                this.copyToExternalDirectory(file_source, pathDir + "common" + File.separator);
            }

            //模板上传文件源目录
            String upload_source = "file" + File.separator + "template" + File.separator + dirName + File.separator;
            //复制模板文件到临时目录
            FileUtil.copyDirectory(upload_source, pathDir + "uploadFile" + File.separator);

            SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");

            //压缩文件名称
            String zipName = dirName + "_" + dateformat.format(new Date()) + ".zip";

            //压缩文件
            //第一个参数：待压缩目录  第二个参数：输出文件
            ZipUtil.pack(PathUtil.defaultExternalDirectory() + File.separator + "WEB-INF"
                            + File.separator + "data" + File.separator + "temp" + File.separator + tempDirName + File.separator,
                    PathUtil.defaultExternalDirectory() + File.separator + "WEB-INF" + File.separator
                            + "data" + File.separator + "templateBackup" + File.separator + zipName);
            //删除临时文件
            localFileManage.removeDirectory("WEB-INF" + File.separator + "data" + File.separator + "temp" + File.separator + tempDirName + File.separator);
        } else {
            error.put("dirName", "目录名称不能为空");
        }
        if (error.size() > 0) {
            return JsonUtils.toJSONString(new RequestResult(ResultCode.FAILURE, error));
        } else {
            return JsonUtils.toJSONString(new RequestResult(ResultCode.SUCCESS, null));
        }
    }

    /**
     * 内部目录复制到外部目录
     *
     * @param resDirPath 源目录路径
     * @param distFolder 目标文件夹
     * @IOException 当操作发生异常时抛出
     */
    private void copyToExternalDirectory(String resDirPath, String distFolder) throws IOException {
        File copyDir = new File(PathUtil.rootPath() + File.separator + resDirPath);
        File distFile = new File(PathUtil.defaultExternalDirectory() + File.separator + (distFolder == null || "".equals(distFolder.trim()) ? "" : distFolder + File.separator));

        if (copyDir.isDirectory()) {
            FileUtils.copyDirectoryToDirectory(copyDir, distFile);
        }
    }

    /**
     * 外部目录复制到内部目录
     *
     * @param resDirPath 源目录路径
     * @param distFolder 目标文件夹
     * @IOException 当操作发生异常时抛出
     */
    private void copyToInternalDirectory(String resDirPath, String distFolder) throws IOException {
        File copyDir = new File(PathUtil.defaultExternalDirectory() + File.separator + resDirPath);
        File distFile = new File(PathUtil.rootPath() + File.separator + (distFolder == null || "".equals(distFolder.trim()) ? "" : distFolder + File.separator));
        if (copyDir.isDirectory()) {
            FileUtils.copyDirectoryToDirectory(copyDir, distFile);
        }
    }

    /**
     * 删除目录 自动路径 jar启动时使用外部路径 IDE启动时使用内部路径
     *
     * @param path 路径 (格式"file"+File.separator+"目录"+File.separator)
     */
    private Boolean removeDirectory(String path) {
        String dir = PathUtil.autoRootPath() + File.separator + path;
        File f = new File(dir);
        return FileUtil.removeDirectory(f);
    }


    /**
     * 模板管理 删除导出模板
     *
     * @param fileName 模板备份文件名称
     */
    @ResponseBody
    @RequestMapping(params = "method=deleteExport", method = RequestMethod.POST)
    public String deleteExport(String fileName) throws Exception {
        Map<String, String> error = new HashMap<>();
        if (fileName != null && !"".equals(fileName.trim())) {
            //替换路径中的..号
            fileName = FileUtil.toRelativePath(fileName);
            //模板文件路径
            String templateFile_path = "WEB-INF" + File.separator + "data" + File.separator + "templateBackup" + File.separator + fileName;
            localFileManage.deleteFile(templateFile_path);
            return JsonUtils.toJSONString(new RequestResult(ResultCode.SUCCESS, null));
        } else {
            error.put("fileName", "文件名称不能为空");
        }
        return JsonUtils.toJSONString(new RequestResult(ResultCode.FAILURE, error));
    }

    /**
     * 模板管理 下载导出模板
     *
     * @param fileName 模板备份文件名称
     */
    @ResponseBody
    @RequestMapping(params = "method=templateDownload", method = RequestMethod.GET)
    public ResponseEntity<byte[]> templateDownload(String fileName, HttpServletRequest request) throws Exception {

        if (fileName == null || "".equals(fileName.trim())) {
            throw new SystemException("文件名称不能为空");
        }
        //替换路径中的..号
        fileName = FileUtil.toRelativePath(fileName);
        String templateFile_path = "WEB-INF" + File.separator + "data" + File.separator + "templateBackup" + File.separator + fileName;

        File file = new File(PathUtil.defaultExternalDirectory() + File.separator + templateFile_path);
        return WebUtil.downloadResponse(FileUtils.readFileToByteArray(file), fileName, request);
    }


    /**
     * 模板管理  导入模板
     *
     * @param fileName 模板文件名称
     */
    @ResponseBody
    @RequestMapping(params = "method=import", method = RequestMethod.POST)
    public String importTemplate(String fileName) throws Exception {
        Map<String, String> error = new HashMap<>();
        if (fileName != null && !"".equals(fileName.trim())) {
            //替换路径中的..号
            fileName = FileUtil.toRelativePath(fileName);
            //模板文件路径
            String templateFile_path = "WEB-INF" + File.separator + "data" + File.separator + "templateBackup" + File.separator + fileName;
            //临时目录名称
            String tempDirName = UUIDUtil.getUUID32();
            //临时目录路径
            String temp_dir_path = "WEB-INF" + File.separator + "data" + File.separator + "temp" + File.separator + tempDirName + File.separator;

            //读取模板文件
            File templateFile = new File(PathUtil.defaultExternalDirectory() + File.separator + templateFile_path);
            if (templateFile.isFile()) {//如果文件存在

                //解压到临时目录
                ZipUtil.unZip(PathUtil.defaultExternalDirectory() + File.separator + templateFile_path, PathUtil.defaultExternalDirectory() + File.separator + temp_dir_path);
                //模板目录名称
                String templateDirName = "";

                File temp_dir_path_file = new File(PathUtil.defaultExternalDirectory() + File.separator + temp_dir_path);
                File[] dirs = temp_dir_path_file.listFiles();
                assert dirs != null;
                for (File f : dirs) {
                    if (f.isDirectory()) {
                        templateDirName = f.getName();
                        break;
                    }
                }

                //删除不安全的jsp和jspx文件
                this.deleteJSP(temp_dir_path);

                if (!"".equals(templateDirName.trim())) {
                    //替换路径中的..号
                    templateDirName = FileUtil.toRelativePath(templateDirName);
                    //验证目录是否重复
                    Themes t = themeService.findTemplateByDirName(templateDirName.trim());
                    if (t == null) {
                        //读取模板数据
                        String templateData_str = FileUtil.readFileToString(temp_dir_path + templateDirName + File.separator + "templateData.data", "UTF-8");

                        if (templateData_str != null && !"".equals(templateData_str.trim())) {
                            ThemeData themeData = JsonUtils.toGenericObject(templateData_str, new TypeReference<ThemeData>() {
                            });
                            Map<String, String> newPrimaryKey = new HashMap<>();//布局数据新主键
                            Themes themes = themeData.getThemes();
                            //旧模板目录名称
                            String oldDirName = "";

                            if (themes != null) {
                                //重设主键
                                themes.setId(null);
                                oldDirName = themes.getDirName();
                                //重设模板目录名称
                                themes.setDirName(templateDirName);
                                //设置模板没选中
                                themes.setUses(false);
                            }
                            List<Layout> layoutList = themeData.getLayoutList();
                            if (layoutList != null && layoutList.size() > 0) {
                                for (Layout layout : layoutList) {
                                    String layoutId = UUIDUtil.getUUID32();
                                    newPrimaryKey.put(layout.getId(), layoutId);
                                    //重设布局主键
                                    layout.setId(layoutId);
                                    //重设模板目录名称
                                    layout.setDirName(templateDirName);
                                }
                            }
                            List<Forum> forumList = themeData.getForumList();
                            if (forumList != null && forumList.size() > 0) {
                                for (Forum forum : forumList) {
                                    //重设版块主键
                                    forum.setId(null);
                                    //重设模板目录名称
                                    forum.setDirName(templateDirName);
                                    //重设布局Id
                                    forum.setLayoutId(newPrimaryKey.get(forum.getLayoutId()));
                                    //更改用户自定义HTML上传文件的模板目录
                                    if ("自定义版块".equals(forum.getForumType()) && "用户自定义HTML".equals(forum.getForumChildType())) {
                                        String formValueJSON = forum.getFormValue();//表单值
                                        if (formValueJSON != null && !"".equals(formValueJSON)) {
                                            Forum_CustomForumRelated_CustomHTML forum_CustomForumRelated_CustomHTML = JsonUtils.toObject(formValueJSON, Forum_CustomForumRelated_CustomHTML.class);
                                            if (forum_CustomForumRelated_CustomHTML != null) {
                                                if (forum_CustomForumRelated_CustomHTML.getHtml_content() != null && !"".equals(forum_CustomForumRelated_CustomHTML.getHtml_content().trim())) {
                                                }
                                                String content = textFilterManage.updatePathName(forum_CustomForumRelated_CustomHTML.getHtml_content(), oldDirName, templateDirName);
                                                forum_CustomForumRelated_CustomHTML.setHtml_content(content);
                                                forum.setFormValue(JsonUtils.toJSONString(forum_CustomForumRelated_CustomHTML));//加入表单值
                                            }
                                        }
                                    }
                                }
                            }
                            themeService.saveTemplateData(themeData);
                        }
                        //templates目录的下一级目录名称
                        String next_templates_dirName = "";
                        File next_templates_temp_dir_path_file = new File(PathUtil.defaultExternalDirectory() + File.separator + temp_dir_path + templateDirName + File.separator + "templates" + File.separator);
                        File[] next_templates_dirs = next_templates_temp_dir_path_file.listFiles();
                        for (File f : next_templates_dirs) {
                            if (f.isDirectory()) {
                                next_templates_dirName = f.getName();
                                break;
                            }
                        }

                        //common目录的下一级目录名称
                        String next_common_dirName = "";
                        File next_common_temp_dir_path_file = new File(PathUtil.defaultExternalDirectory() + File.separator + temp_dir_path + templateDirName + File.separator + "common" + File.separator);
                        File[] next_common_dirs = next_common_temp_dir_path_file.listFiles();
                        for (File f : next_common_dirs) {
                            if (f.isDirectory()) {
                                next_common_dirName = f.getName();
                                break;
                            }
                        }
                        //uploadFile目录的下一级目录名称
                        String next_uploadFile_dirName = "";
                        File next_uploadFile_temp_dir_path_file = new File(PathUtil.defaultExternalDirectory() + File.separator + temp_dir_path + templateDirName + File.separator + "uploadFile" + File.separator);
                        File[] next_uploadFile_dirs = next_uploadFile_temp_dir_path_file.listFiles();
                        for (File f : next_uploadFile_dirs) {
                            if (f.isDirectory()) {
                                next_uploadFile_dirName = f.getName();
                                break;
                            }
                        }

                        if (!"".equals(next_templates_dirName.trim())) {
                            //模板源目录
                            String template_source = temp_dir_path + templateDirName + File.separator + "templates" + File.separator + next_templates_dirName + File.separator;

                            //重命名文件夹名称,和模板名称一致
                            FileUtil.renameFile(template_source, templateDirName);

                            if (PathUtil.isStartupFromJar()) {//jar启动
                                //复制模板文件到模板目录
                                FileUtil.copyDirectory(temp_dir_path + templateDirName + File.separator + "templates" + File.separator + templateDirName + File.separator, "WEB-INF" + File.separator + "front" + File.separator + "templates");
                            } else {//IDE启动	
                                this.copyToInternalDirectory(temp_dir_path + templateDirName + File.separator + "templates" + File.separator + templateDirName + File.separator, "WEB-INF" + File.separator + "front" + File.separator + "templates");
                            }
                        }
                        if (!"".equals(next_common_dirName.trim())) {
                            String file_source = temp_dir_path + templateDirName + File.separator + "common" + File.separator + next_common_dirName + File.separator;
                            //重命名文件夹名称,和模板名称一致
                            FileUtil.renameFile(file_source, templateDirName);

                            if (PathUtil.isStartupFromJar()) {//jar启动
                                //复制模板资源文件到文件目录
                                FileUtil.copyDirectory(temp_dir_path + templateDirName + File.separator + "common" + File.separator + templateDirName + File.separator, "common");

                            } else {//IDE启动	
                                this.copyToInternalDirectory(temp_dir_path + templateDirName + File.separator + "common" + File.separator + templateDirName + File.separator, "static" + File.separator + "common");
                            }
                        }
                        if (!"".equals(next_uploadFile_dirName.trim())) {
                            String upload_source = temp_dir_path + templateDirName + File.separator + "uploadFile" + File.separator + next_common_dirName + File.separator;
                            //重命名文件夹名称,和模板名称一致
                            FileUtil.renameFile(upload_source, templateDirName);
                            //复制模板上传文件到文件目录
                            FileUtil.copyDirectory(temp_dir_path + templateDirName + File.separator + "uploadFile" + File.separator + templateDirName + File.separator, "file" + File.separator + "template");
                        }
                        //删除临时文件
                        localFileManage.removeDirectory("WEB-INF" + File.separator + "data" + File.separator + "temp" + File.separator + tempDirName + File.separator);
                    } else {
                        //删除临时文件
                        localFileManage.removeDirectory("WEB-INF" + File.separator + "data" + File.separator + "temp" + File.separator + tempDirName + File.separator);
                        error.put("fileName", "模板目录已存在");
                    }
                }
            } else {
                error.put("fileName", "文件不存在");
            }
        } else {
            error.put("fileName", "文件名称不能为空");
        }
        if (error.size() > 0) {
            return JsonUtils.toJSONString(new RequestResult(ResultCode.FAILURE, error));
        } else {
            return JsonUtils.toJSONString(new RequestResult(ResultCode.SUCCESS, null));
        }
    }

    /**
     * 模板管理 导入模板列表
     */
    @ResponseBody
    @RequestMapping(params = "method=importTemplateList", method = RequestMethod.GET)
    public String importTemplateList() throws Exception {

        Map<String, String> error = new HashMap<>();

        List<Themes> themesList = new ArrayList<>();

        //模板目录
        String pathDir = "WEB-INF" + File.separator + "data" + File.separator + "templateBackup" + File.separator;

        String[] extensions = null;//后缀名{"doc", "pdf"}
        boolean recursive = false;//是否递归
        Collection<File> files = FileUtils.listFiles(new File(PathUtil.defaultExternalDirectory() + File.separator + pathDir), extensions, recursive);

        // 迭代输出
        for (File file : files) {
            //允许上传图片格式
            List<String> formatList = new ArrayList<>();
            formatList.add("zip");
            //验证文件后缀
            boolean fileSuffix = FileUtil.validateFileSuffix(file.getName(), formatList);
            if (fileSuffix) {
                //读取压缩文件
                try (ZipFile zip = new ZipFile(file)) {
                    Themes themes = new Themes();
                    themes.setFileName(file.getName());
                    Enumeration<ZipArchiveEntry> entry = zip.getEntries();
                    while (entry.hasMoreElements()) {//依次访问各条目
                        ZipArchiveEntry ze = entry.nextElement();
                        String fileName = FileUtil.getName(ze.getName());//文件名称

                        if (themes.getDirName() == null || "".equals(themes.getDirName())) {
                            //截取到等于第二个参数的字符串为止
                            themes.setDirName(StringUtils.substringBefore(ze.getName(), "/"));
                        }
                        //读取配置文件
                        if ("templateData.data".equals(fileName)) {
                            InputStream in = zip.getInputStream(ze);
                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
                            int i;
                            while ((i = in.read()) != -1) {
                                baos.write(i);
                            }
                            String str = baos.toString("utf-8");
                            if (str != null && !"".equals(str)) {
                                ThemeData themeData = JsonUtils.toGenericObject(str, new TypeReference<ThemeData>() {
                                });
                                if (themeData != null) {
                                    if (themeData.getThemes() != null) {
                                        themes.setName(themeData.getThemes().getName());
                                        themes.setIntroduction(themeData.getThemes().getIntroduction());
                                    }
                                }
                            }
                            break;
                        }
                    }
                    themesList.add(themes);
                } catch (Exception e) {
                    error.put("templates", "导入模板列表查询错误");
                    logger.error("导入模板列表", e);
                }
            }
        }

        if (error.size() > 0) {
            return JsonUtils.toJSONString(new RequestResult(ResultCode.FAILURE, error));
        } else {
            return JsonUtils.toJSONString(new RequestResult(ResultCode.SUCCESS, themesList));
        }
    }

    /**
     * 目录重命名
     *
     * @param fileName      文件名称
     * @param directoryName 新目录名称
     */
    @ResponseBody
    @RequestMapping(params = "method=directoryRename", method = RequestMethod.POST)
    public String directoryRename(String fileName, String directoryName) {

        Map<String, String> error = new HashMap<>();

        if (directoryName != null && !"".equals(directoryName.trim())) {
            if (directoryName.length() > 40) {
                error.put("directoryName", "目录名称过长");
            } else {
                //只能输入字母或下划线
                if (!directoryName.matches("^[a-zA-Z][a-zA-Z0-9|_]{2,40}$")) {
                    error.put("directoryName", "只能由字母或数字或下划线组成,并且开头为字母，总长度大于两个字符");
                } else {
                    //验证目录是否重复
                    Themes t = themeService.findTemplateByDirName(directoryName.trim());
                    if (t != null) {
                        error.put("directoryName", "模板目录不能重复");
                    }
                }
            }
        } else {
            error.put("directoryName", "新目录名称不能为空");
        }
        if (fileName != null && !"".equals(fileName.trim())) {
            if (error.size() == 0) {
                //替换路径中的..号
                fileName = FileUtil.toRelativePath(fileName.trim());
                //模板文件路径
                String templateFile_path = "WEB-INF" + File.separator + "data" + File.separator + "templateBackup" + File.separator + fileName;
                //临时目录名称
                String tempDirName = UUIDUtil.getUUID32();
                //临时目录路径
                String temp_dir_path = "WEB-INF" + File.separator + "data" + File.separator + "temp" + File.separator + tempDirName + File.separator;

                //读取模板文件
                File templateFile = new File(PathUtil.defaultExternalDirectory() + File.separator + templateFile_path);

                if (templateFile.isFile()) {//如果文件存在
                    //解压到临时目录
                    ZipUtil.unZip(PathUtil.defaultExternalDirectory() + File.separator + templateFile_path, PathUtil.defaultExternalDirectory() + File.separator + temp_dir_path);

                    //临时目录的下一级目录名称
                    String next_temp_dirName = "";
                    File next_temp_dir_path_file = new File(PathUtil.defaultExternalDirectory() + File.separator + temp_dir_path + File.separator);
                    File[] next_templates_dirs = next_temp_dir_path_file.listFiles();
                    for (File f : next_templates_dirs) {
                        if (f.isDirectory()) {
                            next_temp_dirName = f.getName();
                            break;
                        }
                    }
                    //想命名的原文件夹的路径  
                    File sourceFolder = new File(PathUtil.defaultExternalDirectory() + File.separator + temp_dir_path + next_temp_dirName + File.separator);

                    //将原文件夹名称更改新文件夹名称
                    sourceFolder.renameTo(new File(PathUtil.defaultExternalDirectory() + File.separator + temp_dir_path + directoryName + File.separator));

                    //压缩文件
                    ZipUtil.pack(PathUtil.defaultExternalDirectory() + File.separator + "WEB-INF" + File.separator + "data" + File.separator + "temp" + File.separator + tempDirName + File.separator,
                            PathUtil.defaultExternalDirectory() + File.separator + "WEB-INF" + File.separator + "data" + File.separator + "templateBackup" + File.separator + fileName);//第一个参数：待压缩目录  第二个参数：输出文件
                    //删除临时文件
                    localFileManage.removeDirectory("WEB-INF" + File.separator + "data" + File.separator + "temp" + File.separator + tempDirName + File.separator);
                } else {
                    error.put("fileName", "文件不存在");
                }
            }
        } else {
            error.put("directoryRename", "文件名称不能为空");
        }
        if (error.size() > 0) {
            return JsonUtils.toJSONString(new RequestResult(ResultCode.FAILURE, error));
        } else {
            return JsonUtils.toJSONString(new RequestResult(ResultCode.SUCCESS, null));
        }
    }

    /**
     * 模板文件上传
     */
    @ResponseBody
    @RequestMapping(params = "method=upload", method = RequestMethod.POST)
    public String upload(MultipartFile uploadFile) throws Exception {
        Map<String, String> error = new HashMap<>();
        String path = PathUtil.defaultExternalDirectory() + File.separator + "WEB-INF" + File.separator + "data" + File.separator + "templateBackup";
        File file = new File(path);
        if (!file.exists()) {//如果目录不存在
            file.mkdirs();//生成目录
        }
        if (file.isDirectory() && uploadFile != null && !uploadFile.isEmpty()) {//如果是目录
            //文件大小
            long size = uploadFile.getSize();
            //允许上传格式
            List<String> formatList = new ArrayList<>();
            formatList.add("zip");
            //允许上传大小
            long uploadSize = 1024 * 1024 * 200;//单位为字节  
            //204800000L
            //验证文件后缀
            boolean authentication = FileUtil.validateFileSuffix(uploadFile.getOriginalFilename(), formatList);
            if (!authentication) {
                error.put("uploadFile", "当前文件格式不允许上传");
            }
            if (size > uploadSize) {
                error.put("uploadFile", "文件大小超出200M");
            }
            String newFilename = "";

            //判断文件是否存在
            File templateFile = new File(path + File.separator + uploadFile.getOriginalFilename());

            if (templateFile.isFile()) {//如果文件存在

                //
                char[] character = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
                        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y'};
                //使用指定的字符生成1位长度的随机字符串
                String text = RandomStringUtils.random(2, character);

                newFilename = FileUtil.getBaseName(uploadFile.getOriginalFilename()) + "_" + text + "." + FileUtil.getExtension(uploadFile.getOriginalFilename());

                File _templateFile = new File(path + File.separator + newFilename);
                if (_templateFile.isFile()) {
                    error.put("uploadFile", "文件名称重复,请重命名再上传");
                }
                if (newFilename.length() > 50) {
                    error.put("uploadFile", "文件名称过长");
                }
            } else {
                newFilename = uploadFile.getOriginalFilename();
            }
            if (error.size() == 0) {
                try (FileOutputStream fileoutstream = new FileOutputStream(new File(path, FileUtil.toRelativePath(FileUtil.toSystemPath(newFilename))))) {
                    //文件输出流
                    //写入硬盘
                    fileoutstream.write(uploadFile.getBytes());
                } catch (Exception e) {
                    error.put("uploadFile", "文件上传出错");
                }
            }
        }
        if (error.size() > 0) {
            return JsonUtils.toJSONString(new RequestResult(ResultCode.FAILURE, error));
        } else {
            return JsonUtils.toJSONString(new RequestResult(ResultCode.SUCCESS, null));
        }
    }


    /**
     * 模板管理 设置当前使用的模板
     *
     * @param dirName 模板目录名称
     */
    @ResponseBody
    @RequestMapping(params = "method=setTemplate", method = RequestMethod.POST)
    public String setTemplate(String dirName) throws Exception {
        Map<String, String> error = new HashMap<>();
        if (dirName != null && !"".equals(dirName.trim())) {
            themeService.useTemplate(dirName.trim());
            return JsonUtils.toJSONString(new RequestResult(ResultCode.SUCCESS, null));
        }
        return JsonUtils.toJSONString(new RequestResult(ResultCode.FAILURE, error));
    }

    /**
     * 删除不安全的jsp和jspx文件
     *
     * @param path 路径
     */
    private void deleteJSP(String path) {
        //后缀名{"doc", "pdf"}
        String[] extensions = {"jsp", "jspx"};
        //不区分大小写
        IOFileFilter filter = new SuffixFileFilter(extensions, IOCase.INSENSITIVE);
        Iterator<File> files = FileUtils.iterateFiles(new File(PathUtil.defaultExternalDirectory()
                + File.separator + path), filter, DirectoryFileFilter.DIRECTORY);
        // 迭代输出
        while (files.hasNext()) {
            File file = files.next();
            if (file.exists() && file.isFile()) {
                boolean state = file.delete();
                if (!state) {
                    try {
                        //清空内容
                        FileUtils.writeStringToFile(file, "", "UTF-8");
                        state = file.delete();
                    } catch (IOException e) {
                        logger.error("删除文件 " + file.getAbsolutePath(), e);
                    }
                }
            }
        }
    }
}
